package org.jsets.fastboot.security.rememberme;

import javax.servlet.http.HttpServletRequest;
import org.jsets.fastboot.util.StringUtils;
import org.jsets.fastboot.security.SecurityUtils;
import org.jsets.fastboot.security.authc.AuthcRequest;
import org.jsets.fastboot.security.authc.AuthcResult;
import org.jsets.fastboot.security.config.SecurityProperties;
import org.jsets.fastboot.security.token.TokenStub;
import cn.hutool.crypto.SecureUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;

@Slf4j
public class RememberMeManager {

	public static final String REMEMBER_ME_HEADER_PARAM_NAME = "X-remember-me";

	private SecurityProperties properties;

	public RememberMeManager(SecurityProperties properties) {
		this.properties = properties;
	}

	public String issueRememberToken(AuthcRequest authcRequest) {
		String id = StringUtils.getUUID();
		String tokenSignKey = this.properties.getTokenSignKey();
		Long rememberMeTimeout = Long.valueOf(this.properties.getRememberMeTimeout());
		String aesSignKey = this.properties.getAesSecretKey();
		String ciphertext = SecureUtil.aes(aesSignKey.getBytes()).encryptHex(authcRequest.getUsername());
		String token = SecurityUtils.issueJWT(id, ciphertext, tokenSignKey, rememberMeTimeout);
		log.info("remember me token[{}]", token);
		return token;
	}

	public boolean isRememberMeRequest(HttpServletRequest request) {
		if (StringUtils.hasText(request.getHeader(REMEMBER_ME_HEADER_PARAM_NAME))) {
			return true;
		}
		return false;
	}

	public AuthcResult rememberMeLogin(String rememberMeIdentity) throws AuthenticationException {
		String username = this.validateRememberToken(rememberMeIdentity);
		AuthcRequest authcRequest = new AuthcRequest();
		authcRequest.setUsername(username);
		AuthcResult authcResult = SecurityUtils.login(authcRequest);
		log.info("[{}]RememberMe登陆成功", username);
		return authcResult;
	}

	private String validateRememberToken(String identity) throws AuthenticationException {
		TokenStub stub = SecurityUtils.validateJWT(identity);
		return stub.getUsername();
	}

}